/*!
\copyright  Copyright (c) 2025 Qualcomm Technologies International, Ltd.
            All Rights Reserved.
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\file      
\ingroup    stats_monitor
\brief      Some utilities to log statistics 
*/
#include "vm.h"

/* Lookup table to associate dB values to Q1.31 values.
   value_in_db = 20*log10(value_q1dot31 / 2**31).
   value_q1dot31 = 2**31 * 10**(value_in_db/20).
*/
static const int32 q31_to_db_lookup_table[] = {
/* 0.0 dB*/ 0x7fffffff,
/*-1.0 dB*/ 0x721482bf,
/*-2.0 dB*/ 0x65ac8c2f,
/*-3.0 dB*/ 0x5a9df7ab,
/*-4.0 dB*/ 0x50c335d3,
/*-5.0 dB*/ 0x47faccf0,
/*-6.0 dB*/ 0x4026e73c,
/*-7.0 dB*/ 0x392ced8d,
/*-8.0 dB*/ 0x32f52cfe,
/*-9.0 dB*/ 0x2d6a866f,
/*-10.0 dB*/ 0x287a26c4,
/*-11.0 dB*/ 0x241346f5,
/*-12.0 dB*/ 0x2026f30f,
/*-13.0 dB*/ 0x1ca7d767,
/*-14.0 dB*/ 0x198a1357,
/*-15.0 dB*/ 0x16c310e3,
/*-16.0 dB*/ 0x144960c5,
/*-17.0 dB*/ 0x12149a5f,
/*-18.0 dB*/ 0x101d3f2d,
/*-19.0 dB*/ 0xe5ca14c,
/*-20.0 dB*/ 0xccccccc,
/*-21.0 dB*/ 0xb687379,
/*-22.0 dB*/ 0xa2adad1,
/*-23.0 dB*/ 0x90fcbf7,
/*-24.0 dB*/ 0x8138561,
/*-25.0 dB*/ 0x732ae18,
/*-26.0 dB*/ 0x66a4a52,
/*-27.0 dB*/ 0x5b7b15a,
/*-28.0 dB*/ 0x518847f,
/*-29.0 dB*/ 0x48aa70b,
/*-30.0 dB*/ 0x40c3713,
/*-31.0 dB*/ 0x39b8718,
/*-32.0 dB*/ 0x337184e,
/*-33.0 dB*/ 0x2dd958a,
/*-34.0 dB*/ 0x28dcebb,
/*-35.0 dB*/ 0x246b4e3,
/*-36.0 dB*/ 0x207567a,
/*-37.0 dB*/ 0x1cedc3c,
/*-38.0 dB*/ 0x19c8651,
/*-39.0 dB*/ 0x16fa9ba,
/*-40.0 dB*/ 0x147ae14,
/*-41.0 dB*/ 0x1240b8c,
/*-42.0 dB*/ 0x1044914,
/*-43.0 dB*/ 0xe7facb,
/*-44.0 dB*/ 0xcec089,
/*-45.0 dB*/ 0xb8449c,
/*-46.0 dB*/ 0xa43aa1,
/*-47.0 dB*/ 0x925e89,
/*-48.0 dB*/ 0x8273a6,
/*-49.0 dB*/ 0x7443e7,
/*-50.0 dB*/ 0x679f1b,
/*-51.0 dB*/ 0x5c5a4f,
/*-52.0 dB*/ 0x524f3b,
/*-53.0 dB*/ 0x495bc1,
/*-54.0 dB*/ 0x416179,
/*-55.0 dB*/ 0x3a4549,
/*-56.0 dB*/ 0x33ef0c,
/*-57.0 dB*/ 0x2e4939,
/*-58.0 dB*/ 0x2940a1,
/*-59.0 dB*/ 0x24c42c,
/*-60.0 dB*/ 0x20c49b,
/*-61.0 dB*/ 0x1d345a,
/*-62.0 dB*/ 0x1a074e,
/*-63.0 dB*/ 0x1732ad,
/*-64.0 dB*/ 0x14acda,
/*-65.0 dB*/ 0x126d42,
/*-66.0 dB*/ 0x106c43,
/*-67.0 dB*/ 0xea30d,
/*-68.0 dB*/ 0xd0b90,
/*-69.0 dB*/ 0xba063,
/*-70.0 dB*/ 0xa5cb5,
/*-71.0 dB*/ 0x93c3b,
/*-72.0 dB*/ 0x83b1f,
/*-73.0 dB*/ 0x755f9,
/*-74.0 dB*/ 0x689bf,
/*-75.0 dB*/ 0x5d3ba,
/*-76.0 dB*/ 0x53181,
/*-77.0 dB*/ 0x4a0ec,
/*-78.0 dB*/ 0x42010,
/*-79.0 dB*/ 0x3ad37,
/*-80.0 dB*/ 0x346dc,
/*-81.0 dB*/ 0x2eba2,
/*-82.0 dB*/ 0x29a54,
/*-83.0 dB*/ 0x251de,
/*-84.0 dB*/ 0x21149,
/*-85.0 dB*/ 0x1d7b9,
/*-86.0 dB*/ 0x1a46d,
/*-87.0 dB*/ 0x176b4,
/*-88.0 dB*/ 0x14df4,
/*-89.0 dB*/ 0x129a3,
/*-90.0 dB*/ 0x10945
};

const uint16 clock_id_to_mhz_lookup_table[] = {
    /* 0 -> 192 MHz */ 192,
    /* 1 -> 268 MHz */ 268,
    /* 2 -> 336 MHz */ 336,
    /* 3 -> 500 MHz */ 500
};

int16 statsMonitorUtils_Q31ToDb(int32 value)
{
  uint16 table_size = sizeof(q31_to_db_lookup_table) / sizeof(int32);
  uint16 index = table_size / 2;
  uint16 index_low_boundary = 0;
  uint16 index_high_boundary = table_size - 1;

  if(value < q31_to_db_lookup_table[index_high_boundary])
      return -index_high_boundary;

  while(index > index_low_boundary &&
        index < index_high_boundary)
  {
      int32 value_in_table = q31_to_db_lookup_table[index];
      if(value > value_in_table)
      {
          index_high_boundary = index;
          index = index_low_boundary + (index - index_low_boundary)/2;
      }
      else if(value < value_in_table)
      {
          index_low_boundary = index;
          index = index + (index_high_boundary - index)/2;
      }
      else
          break;
  }

  return -index;
}

uint16 statsMonitorUtils_ClockIdToMhz(uint16 clock_id)
{
    if(clock_id < sizeof(clock_id_to_mhz_lookup_table)/sizeof(uint16))
    {
        return clock_id_to_mhz_lookup_table[clock_id];
    }

    return 0;
}